//
//  DKOpenGLVideoView.m
//  DKShortVideo
//
//  Created by Keer_LGQ on 2018/4/1.
//  Copyright © 2018年 DK. All rights reserved.
//

#import "DKOpenGLPlayerView.h"
#import "DKVideoPlayerManger.h"
#import "OpenGLPixelBufferView.h"
#import "DKBufferRenderProtocol.h"
#import "DKGPUFiterRenderer.h"

@interface DKOpenGLPlayerView () <DKVideoPlayerDelegate>
{
    BOOL _addedObservers;
    BOOL _allowedToUseGPU;
    BOOL _autoPlay;
    CGFloat _position;
    dispatch_semaphore_t _frameRenderingSemaphore;
}

@property (nonatomic ,strong) OpenGLPixelBufferView *previewView;
@property (nonatomic ,strong) DKVideoPlayerManger *playerManger;
@property(nonatomic, strong) __attribute__((NSObject)) CVPixelBufferRef currentPreviewPixelBuffer;
@property (nonatomic, strong) id <DKBufferRenderProtocol> renderer;

@end

@implementation DKOpenGLPlayerView

- (instancetype)initWithFrame:(CGRect)frame autoPlay:(BOOL)autoPlay
{
    if (self = [super initWithFrame:frame]) {
        [self configNotification];
  
        _position = 0;
        _autoPlay = autoPlay;
        _isFilter = NO;
        _frameRenderingSemaphore = dispatch_semaphore_create(1);
    }
    return self;
}

- (void)dealloc
{
    if ( _addedObservers ){
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
        [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
    }
}
#pragma mark public
- (BOOL)play
{
    [self configPreview];
    return [_playerManger playPosition:0];
}


- (void)stop
{
    [_playerManger stop];
}

- (void)pause
{
    [_playerManger pause];
    
}

- (BOOL)isPlaying
{
    if ([_playerManger getStatus] == PLAYING) {
        return YES;
    }
    return NO;
}

- (void)willMoveToSuperview:(UIView *)newSuperview {
    if (!newSuperview) {
        [_playerManger unload];

    }
    [super willMoveToSuperview:newSuperview];
}

- (void)didMoveToSuperview {
    [super didMoveToSuperview];
    if (self.superview) {
        if (_autoPlay) {
            [self play];
        }
    }
}

- (void)layoutSubviews
{
    [self addSubview:self.previewView];
}

- (void)configNotification
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationDidEnterBackground)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:[UIApplication sharedApplication]];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationWillEnterForeground)
                                                 name:UIApplicationWillEnterForegroundNotification
                                               object:[UIApplication sharedApplication]];
    _addedObservers = YES;
    
    _allowedToUseGPU = ( [UIApplication sharedApplication].applicationState != UIApplicationStateBackground );
    
}

- (void)configPreview
{
//    __weak typeof(self) weakSelf = self;
//    [self.playerManger setFrameBufferBlock:^(CVPixelBufferRef pixelBuffer, NSLock * bufferLock) {
//
//
//    }];
}


- (OpenGLPixelBufferView *)previewView
{
    if (!_previewView) {
        _previewView = [[OpenGLPixelBufferView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width,self.frame.size.height)];
  
    }
    return _previewView;
}

- (DKVideoPlayerManger *)playerManger
{
    if (!_playerManger) {
        _playerManger = [[DKVideoPlayerManger alloc] initWithDelegate:self callbackQueue:dispatch_get_main_queue()];
    }
    return _playerManger;
}

- (id<DKBufferRenderProtocol>)renderer
{
    if (!_renderer) {
        _renderer = [[DKGPUFiterRenderer alloc] init];
    }
    return _renderer;
}

- (void)setVideoUrl:(NSString *)videoUrl
{
    _videoUrl = videoUrl;
    [self.playerManger loadMedia:videoUrl playImmediately:_autoPlay playerType:PLAYER_TYPE_ON_PIXELBUFFER];
}


- (void)applicationDidEnterBackground
{
    // Avoid using the GPU in the background
    _allowedToUseGPU = NO;
    [_playerManger pause];
    // We reset the OpenGLPixelBufferView to ensure all resources have been cleared when going to the background.
    [_previewView reset];
}

- (void)applicationWillEnterForeground
{
    [self play];
    _allowedToUseGPU = YES;
}

#pragma mark DKVideoPlayerDelegate
- (void)videoPlay:(DKVideoPlayerManger *)player previewPixelBufferReadyForDisplay:(CVPixelBufferRef)pixelBuffer
{
    @autoreleasepool {
        __block CVPixelBufferRef renderedPixelBuffer = NULL;
        if (dispatch_semaphore_wait(_frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0)
        {
            return;
        }

        if (pixelBuffer != NULL) {
            if (self.isFilter) {
                
                const CMVideoDimensions srcDimensions = { (int32_t)CVPixelBufferGetWidth(pixelBuffer), (int32_t)CVPixelBufferGetHeight(pixelBuffer) };
                // config filter offscreen Buffer Handle
                [self.renderer prepareForInputWithVideoDimensions:srcDimensions outputRetainedBufferCountHint:RETAINED_BUFFER_COUNT];
                // filter render
                renderedPixelBuffer = [self.renderer copyRenderedPixelBuffer:pixelBuffer];
                
            }
            else {
                renderedPixelBuffer = pixelBuffer;
            }
            [self.previewView displayPixelBuffer:renderedPixelBuffer];
        }
        if (NULL != pixelBuffer) {
            // Release the latest sample buffer
            CFRelease(pixelBuffer);
        }else{
            [self.previewView flushPixelBufferCache];
        }
        if (self.isFilter && NULL != renderedPixelBuffer) {
            CFRelease( renderedPixelBuffer );
        }else {
            [self.previewView flushPixelBufferCache];
        }
        dispatch_semaphore_signal(_frameRenderingSemaphore);
    }
}

- (void)videoPlaydidPlaybackEnd:(DKVideoPlayerManger *)player
{
    if (self.playbackReachedEndBlock) {
        self.playbackReachedEndBlock();
    }
}

- (void)videoPlaydidPlaybackReadyToPlay:(DKVideoPlayerManger *)player {
    
}


- (void)videoPlaydidPlaybackStart:(DKVideoPlayerManger *)player {
    
}

@end
